<?php
declare(strict_types=1);
/**
 * Created by PhpStorm
 * User: Administrator
 * Date: 2023/8/10
 * Time: 14:19:05
 */

namespace Service\CommodityService;

use _PHPStan_b8e553790\Nette\Neon\Exception;
use App\Model\BbcModel\Goods;
use App\Model\BbcModel\GoodsAggregation;
use App\Model\BbcModel\GoodsAggregationGoods;
use Composer\IO\NullIO;
use Service\Code\Normal;
use Hyperf\DbConnection\Db;
use Service\BaseService;

/**
 * 聚合商品
 */
class AggregationGoodsService extends BaseService
{
    public function makeWhere($param){
        $where = [
            ['cid','=',$param['cid']],
            ['sid','=',$param['sid']],
            ['df','=',0],
        ];

        if(isset($param['name']) && $param['name'] != ''){
            $where[] = ['name','like',"%{$param['name']}%"];
        }

        if(isset($param['word']) && $param['word'] != ''){
            $where[] = ['name|skucode|barcode','=',"{$param['name']}"];
        }

        return $where;
    }

    /**
     * 聚合商品列表
     * @param $param
     * @return array
     */
    public function goodsList(array $param){
        $page = $param['page'] ?? 1;
        $limit = $param['limit'] ?? 10;

        $where = $this->makeWhere($param);
        $data_list = GoodsAggregation::instance()
            ->where($where)
            ->paginate($limit,['id','name','show_name','cd'],'page',$page);

        $list = $data_list->items();
        $total = $data_list->total();

        foreach ($list as &$v){
            $goods_list = GoodsAggregationGoods::instance()
                ->leftJoin('ly_goods','ly_goods.id','=','ly_goods_aggregation_goods.goods_id')
                ->where(['ly_goods_aggregation_goods.aggregation_id'=>$v['id'],'ly_goods_aggregation_goods.df'=>0,'ly_goods.df'=>0])
                ->pluck('num_storage')->toArray();
            $v['sku_num'] = count($goods_list);

            $v['num_storage'] = array_sum($goods_list);

            $v['cd'] = date('Y-m-d H:i:s',$v['cd']);
        }

        return Normal::returnCode(Normal::SUC,'请求成功',['list'=>$list,'total'=>$total]);
    }

    public function add(array $param)
    {
        if(!isset($param['name']) || !$param['name']){
            return Normal::returnCode(Normal::FAIL,'聚合商品名称不能为空');
        }

        if(!isset($param['show_name']) || !$param['show_name']){
            return Normal::returnCode(Normal::FAIL,'显示名称不能为空');
        }

        Db::beginTransaction();
        try{

            $aggregation_id = GoodsAggregation::instance()
                ->insertGetId([
                    'sid'       => $param['sid'],
                    'cid'       => $param['cid'],
                    'name'      => $param['name'],
                    'show_name' => $param['show_name'],
                    'cd'        => time(),
                    'md'        => time(),
                ]);

            if(isset($param['goods_list']) && $param['goods_list']){ //添加了商品
                $insert_goods_data = [];
                foreach ($param['goods_list'] as $k=>$v){
                    if(!isset($v['label']) || !$v['label']){
                        throw new \Exception('标签文字不能为空');
                    }
                    $insert_goods_data[$k]['sid']            = $param['sid'];
                    $insert_goods_data[$k]['cid']            = $param['cid'];
                    $insert_goods_data[$k]['aggregation_id'] = $aggregation_id;
                    $insert_goods_data[$k]['goods_id']       = $v['goods_id'];
                    $insert_goods_data[$k]['label']          = $v['label'];
                    $insert_goods_data[$k]['sort']           = $k;
                    $insert_goods_data[$k]['cd']             = time();
                    $insert_goods_data[$k]['md']             = time();
                }

                GoodsAggregationGoods::instance()
                    ->insert($insert_goods_data);
            }
            Db::commit();
            return Normal::returnCode(Normal::SUC,'新增成功');
        }catch (\Exception $e){
            Db::rollBack();
            return Normal::returnCode(Normal::FAIL,'新增失败：'.$e->getMessage());
        }
    }

    public function addGoods($param){
        if(!isset($param['id']) || !$param['id']){
            return Normal::returnCode(Normal::FAIL,'缺少聚合商品ID');
        }

        if(!isset($param['goods_list']) || !$param['goods_list'] || !is_array($param['goods_list'])){
            return Normal::returnCode(Normal::FAIL,'缺少商品');
        }

        if(!isset($param['name']) || !$param['name']){
            return Normal::returnCode(Normal::FAIL,'聚合商品名称不能为空');
        }

        if(!isset($param['show_name']) || !$param['show_name']){
            return Normal::returnCode(Normal::FAIL,'显示名称不能为空');
        }

        $has = GoodsAggregation::instance()
            ->where(['id'=>$param['id'],'cid'=>$param['cid'],'df'=>0])
            ->exists();
        if(!$has){
            return Normal::returnCode(Normal::FAIL,'聚合商品不存在');
        }

        $old_goods = GoodsAggregationGoods::instance()
            ->where(['aggregation_id'=>$param['id'],'df'=>0])
            ->select(['id','goods_id'])
            ->get()->toArray();
        $old_goods_map = array_column($old_goods,null,'goods_id');
        $old_goods_ids = array_column($old_goods,'goods_id');

        $max_sort = GoodsAggregationGoods::instance()->where(['aggregation_id'=>$param['id']])->max('sort') + 1;
        $sort = $max_sort;
        $insert_goods_data = [];
        $update_goods_data = [];
        $i = 0;
        foreach ($param['goods_list'] as $v){
            $goods_id = Goods::instance()->where(['id'=>$v['goods_id'],'df'=>0,'is_trade'=>1])->first();
            if(!$goods_id){
                return Normal::returnCode(Normal::FAIL,'商品不存在或不是自建商品');
            }
            if(!$v['label']){
                return Normal::returnCode(Normal::FAIL,'标签文字不能为空');
            }
            if(in_array($v['goods_id'],$old_goods_ids)){ //之前已添加过此商品
                $update_goods_data[$i]['id'] = $old_goods_map[$v['goods_id']]['id'];
                $update_goods_data[$i]['label'] = $v['label'];
                $update_goods_data[$i]['md'] = time();
            }else{
                $insert_goods_data[$i]['sid']            = $param['sid'];
                $insert_goods_data[$i]['cid']            = $param['cid'];
                $insert_goods_data[$i]['aggregation_id'] = $param['id'];
                $insert_goods_data[$i]['goods_id']       = $v['goods_id'];
                $insert_goods_data[$i]['label']          = $v['label'];
                $insert_goods_data[$i]['sort']           = $sort;
                $insert_goods_data[$i]['cd']             = time();
                $insert_goods_data[$i]['md']             = time();
                $sort++;
            }
            $i++;

        }
        Db::beginTransaction();
        try{

            GoodsAggregation::instance()
                ->where(['id'=>$param['id']])
                ->update(['name'=>$param['name'],'show_name'=>$param['show_name'],'md'=>time()]);

            if($insert_goods_data){
                GoodsAggregationGoods::instance()
                    ->insert($insert_goods_data);
            }

            if($update_goods_data){
                $table = GoodsAggregationGoods::instance();
                (new \Service\MoveUpDownService\UpdateBatchService())->updateBatch($table,$update_goods_data,'id');
            }

            Db::commit();
        }catch (\Exception $e){
            Db::rollBack();
            return Normal::returnCode(Normal::FAIL,'添加失败：'.$e->getMessage());
        }
        return Normal::returnCode(Normal::SUC,'添加成功');
    }

    public function details($param) : array{
        $page = $param['page'] ?? 1;
        $limit = $param['limit'] ?? 10;

        if(!isset($param['id']) || !$param['id']){
            return Normal::returnCode(Normal::FAIL,'缺少聚合商品ID');
        }
        $info = GoodsAggregation::instance()
            ->where(['id'=>$param['id'],'cid'=>$param['cid'],'df'=>0])
            ->first();
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'聚合商品不存在');
        }

        $data_list = GoodsAggregationGoods::instance()
            ->leftJoin('ly_goods','ly_goods.id','=','ly_goods_aggregation_goods.goods_id')
            ->where(['ly_goods_aggregation_goods.aggregation_id'=>$param['id']])
            ->where(['ly_goods.df'=>0])
            ->select(['ly_goods_aggregation_goods.id','ly_goods.id','ly_goods.skucode','ly_goods.barcode','ly_goods.name','ly_goods.img','ly_goods.is_bonded','ly_goods.status','ly_goods.num_storage','ly_goods_aggregation_goods.label','ly_goods_aggregation_goods.sort'])
            ->paginate($limit,['id','name','show_name','cd'],'page',$page);

        $list = $data_list->items();
        $total = $data_list->total();

        foreach ($list as &$v){

            if($v['status'] == 0){
                $v['status_text'] = '下架';
            }else{
                $v['status_text'] = '上架';
            }

            $v['is_bonded_text'] = Goods::instance()->is_bonded[$v['is_bonded']] ?? '';
        }

        $returnData['name']      = $info['name'];
        $returnData['show_name'] = $info['show_name'];
        $returnData['list']      = $list;
        $returnData['total']     = $total;

        return Normal::returnCode(Normal::SUC,'请求成功',$returnData);

    }

    public function editSort($param) : array{
        if(!isset($param['id']) || !$param['id']){
            return Normal::returnCode(Normal::FAIL,'ID不能为空');
        }

        if(!isset($param['sort']) || !is_numeric($param['sort'])){
            return Normal::returnCode(Normal::FAIL,'排序参数不正确');
        }

        $has = GoodsAggregationGoods::instance()
            ->where(['id'=>$param['id'],'cid'=>$param['cid'],'df'=>0])
            ->exists();
        if(!$has){
            return Normal::returnCode(Normal::FAIL,'数据不存在');
        }

        $res = GoodsAggregationGoods::instance()
            ->where(['id'=>$param['id']])
            ->update(['sort'=>$param['sort'],'md'=>time()]);

        if(!$res){
            return Normal::returnCode(Normal::FAIL,'操作失败');
        }
        return Normal::returnCode(Normal::SUC,'操作成功');
    }

    public function del($param) : array{
        if(!isset($param['aggregation_id']) || !$param['aggregation_id']){
            return Normal::returnCode(Normal::FAIL,'缺少聚合ID');
        }
        if(!isset($param['id']) || !$param['id']){
            return Normal::returnCode(Normal::FAIL,'缺少删除ID');
        }


        $has = GoodsAggregationGoods::instance()
            ->where(['id'=>$param['id'],'aggregation_id'=>$param['aggregation_id'],'cid'=>$param['cid'],'df'=>0])
            ->exists();
        if(!$has){
            return Normal::returnCode(Normal::FAIL,'数据不存在');
        }

        $res = GoodsAggregationGoods::instance()
            ->where(['id'=>$param['id']])
            ->delete();

        if(!$res){
            return Normal::returnCode(Normal::FAIL,'删除失败');
        }
        return Normal::returnCode(Normal::SUC,'删除成功');

    }

    public function moveUpDown($param){
        if(!isset($param['id']) || !$param['id']){
            return Normal::returnCode(Normal::FAIL,'缺少聚合商品ID');
        }
        if(!isset($param['type']) || !$param['type']){
            return Normal::returnCode(Normal::FAIL,'缺少移动类型参数');
        }
        $table = GoodsAggregationGoods::instance();
        $where = [
            ['cid','=',$param['cid']],
            ['sid','=',$param['sid']],
            ['df','=',0],
        ];
        return (new \Service\MoveUpDownService\MoveUpDownService())->moveUpDown($param['id'],$param['type'],$table,$where,'sort');
    }

    public function setTop($param) : array{
        if(!isset($param['id']) || !$param['id']){
            return Normal::returnCode(Normal::FAIL,'缺少聚合商品ID');
        }

        $table = GoodsAggregationGoods::instance();
        $where = [
            ['cid','=',$param['cid']],
            ['sid','=',$param['sid']],
            ['df','=',0],
        ];
        $res = (new \Service\MoveUpDownService\MoveUpDownService())->setTop($param['id'],$table,$where,'sort',$param['type']);
        if($res['code'] != Normal::SUC){
            return Normal::returnCode(Normal::FAIL,$res['msg']);
        }
        return Normal::returnCode(Normal::SUC,'操作成功');
    }
}